package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
	"github.com/ngaut/log"
	"strings"
	"time"
)

const (
	CONFIG_FILE = "conf/config.toml"
)

type httpConfig struct {
	Ip   string `toml:"ip"`
	Port int    `toml:"port"`
}

// 获取地址
func (h httpConfig) GetAddr() string {
	return fmt.Sprintf("%s:%d", h.Ip, h.Port)
}

type logConfig struct {
	On     bool   `toml:"log_on"`
	Dir    string `toml:"log_dir"`
	File   string `toml:"log_file"`
	Level  string `toml:"log_level"`
	Rotate string `toml:"log_rotate"`
}

// 获取文件名
func (l logConfig) getFilePath() string {
	path := strings.TrimRight(l.Dir, "/")
	file := l.File
	if file == "" {
		file = "backup.log"
	}
	return fmt.Sprintf("%s/%s", path, file)
}

func (l logConfig) Setting() {
	filePath := l.getFilePath()
	if l.On && filePath != "" {
		log.SetOutputByName(filePath)
		log.SetLevelByString(l.Level)
		if l.Rotate == "H" || l.Rotate == "" {
			log.SetRotateByHour()
		} else {
			log.SetRotateByDay()
		}
		log.SetHighlighting(false)
	}
}

// database configs
type dbConfig struct {
	Host     string `toml:"host"`
	Port     int    `toml:"port"`
	Username string `toml:"username"`
	Password string `toml:"password"`
	DBName   string `toml:"dbname"`
}

func (config dbConfig) FormatDBConnection() string {
	return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True",
		config.Username, config.Password, config.Host, config.Port, config.DBName)
}

type Configuration struct {
	App   appConfig 			`toml:"app"`
	Http  httpConfig             `toml:"http"`
	Log   logConfig              `toml:"log"`
	Redis map[string]redisConfig `toml:"redis"`
	Db    map[string]dbConfig    `toml:"db"`
}

type redisConfig struct {
	Host string `toml:"host"`
	Port int    `toml:"port"`
	DB   int    `toml:"db"`
	Auth string `toml:"auth"`
}

func (r redisConfig) redisPool() *redis.Pool {
	return &redis.Pool{
		MaxIdle:     100,
		IdleTimeout: 240 * time.Second,
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", fmt.Sprintf("%s:%d", r.Host, r.Port), redis.DialDatabase(r.DB))
			if err != nil {
				return nil, err
			}
			if r.Auth != "" {
				if _, err := c.Do("AUTH", r.Auth); err != nil {
					c.Close()
					return nil, err
				}
			}
			return c, err
		},

		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			if time.Since(t) < 5*time.Second {
				return nil
			}
			_, err := c.Do("PING")
			return err
		},
	}
}

type appConfig struct {
	Name 	string 		`toml:"name"`
}

func newConfiguration() Configuration {
	return Configuration{
		Db:    make(map[string]dbConfig),
	}
}
